/**
 * 
 */
package sailing.utils;

import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import cjlite.logger.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * Prompt Dialog
 * 
 * @author kevin
 * 
 */
public class PD {
	private static Logger logger = Logger.thisClass();

	public static void execute(JComponent component, STask sTask) {
		Window window = SwingUtilities.getWindowAncestor(component);

		if (window == null) {
			logger.error("the componenet[{0}] has no window, it should have", component.toString());
		}

		PromptTask pt = new PromptTask(window, sTask);
		pt.start();
	}

	public static class PromptTask extends Thread {

		private Window owner;

		private PromptDialog pd;

		private STask stask;

		public PromptTask(Window window, STask sTask) {
			super("PromptTask");
			owner = window;
			this.stask = sTask;
		}

		public void run(STask sTask) {
			this.preRun();
			this.stask.setCaller(this);
			this.stask.run();
			this.postRan();
		}

		private void postRan() {
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					pd.setVisible(false);
				}
			});

			if (stask.hasAfterMessage()) {
				SwingUtilities.invokeLater(new Runnable() {

					@Override
					public void run() {
						JOptionPane.showMessageDialog(owner, stask.getAfterMsg(), "提示", JOptionPane.INFORMATION_MESSAGE);
					}
				});
			}
		}

		private void preRun() {
			pd = new PromptDialog(owner);
			try {
				// final CountDownLatch cdl = new CountDownLatch(1);
				SwingUtilities.invokeLater(new Runnable() {

					@Override
					public void run() {
						pd.setVisible(true);
						// cdl.countDown();
					}
				});

				// cdl.await();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		public void updateMsg(final String msg) {
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					pd.updateMsg(msg);
				}
			});
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Thread#run()
		 */
		@Override
		public void run() {
			this.run(this.stask);
		}

	}

	public static class PromptDialog extends JDialog {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JLabel msgLabel;

		public PromptDialog(Window owner) {
			super(owner, "提示", ModalityType.APPLICATION_MODAL);
			this.initialUI();
			this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		}

		public void updateMsg(String msg) {
			this.msgLabel.setText(msg);
		}

		private void initialUI() {
			JPanel root = new JPanel();
			FormLayout layout = new FormLayout("10dlu,f:150dlu,10dlu", "10dlu,f:50dlu,10dlu");
			root.setLayout(layout);
			//
			CellConstraints cc = new CellConstraints();
			msgLabel = new JLabel();
			root.add(msgLabel, cc.xy(2, 2));
			//
			this.setLayout(new BorderLayout());
			this.add(root, BorderLayout.CENTER);
			this.pack();

			this.setToCenter();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.Dialog#isResizable()
		 */
		@Override
		public boolean isResizable() {
			return false;
		}

		private void setToCenter() {
			Rectangle screenRect = this.getGraphicsConfiguration().getBounds();
			Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(this.getGraphicsConfiguration());

			int centerWidth = screenRect.width < this.getSize().width ? screenRect.x : screenRect.x + screenRect.width
					/ 2 - this.getSize().width / 2;
			int centerHeight = screenRect.height < this.getSize().height ? screenRect.y : screenRect.y
					+ screenRect.height / 2 - this.getSize().height / 2;

			centerHeight = centerHeight < screenInsets.top ? screenInsets.top : centerHeight;

			this.setLocation(centerWidth, centerHeight);
		}

	}

}
